package com.atguigu.gulimall.order.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
 * feign 的配置类
 *  (解决 Feign 远程调用请求头丢失问题)
 */
@Configuration
public class GuliFeignConfig {
    @Bean("requestInterceptor")
    public RequestInterceptor requestInterceptor(){
        return new RequestInterceptor(){
            @Override
            public void apply(RequestTemplate requestTemplate) {
                //1、使用 RequestContextHolder 拿到刚进来的请求
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                if (attributes != null){
                    HttpServletRequest request = attributes.getRequest();    //获取请求 (老请求)
                    if (request != null){
                        //2、同步请求头数据：Cookie
                        String cookie = request.getHeader("Cookie");    //从老请求的请求头里面获取 Cookie
                        //3、给新请求加上老请求的 Cookie
                        requestTemplate.header("Cookie", cookie);
                        System.out.println("feign 远程之前先执行 RequestInterceptor.apply()");
                    }}}};}}


/**
 * 1、feign 远程调用的请求头中没有含有 JSESSIONID 的 cookie，所以也就不能得到服务端的 session 数据，cart 服务就认为没登录，获取不了用户信息
 * 2、但是在 feign 的调用过程中，会使用容器中的 RequestInterceptor 对 RequestTemplate 进行处理，
 *    因此我们可以通过向容器中添加自定义的 RequestInterceptor, 为请求加上 cookie。
 * 3、RequestContextHolder 为 SpingMVC 中共享 request 数据的上下文，底层由 ThreadLocal 实现。
 *    经过 RequestInterceptor 处理后的请求如下，已经加上了请求头的 Cookie 信息
 */
